/*
 * StringUtils.java
 *
 * Created on 23 May 2006, 19:53
 *
 * Copyright (C)
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA
 */

package com.grubby.utils;

import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * String Utilities.
 * This class provides a bunch of methods to aid String manipulation.
 *
 * It was originally taken from examples provided by Jonathan Vaughan of
 * Monks/Vaughan Ltd.
 *
 * @author A. HARMEL-LAW. E: andrew.harmel.law@gmail.com
 * @author J.S. Vaughan
 * @version 0.1
 */
public final class StringUtils {

    public static final Logger LOGGER = Logger.getLogger("com.grubby.utils.StringUtils");
    /* Log Strings */
    private static final String NULL_PARAMETER_EX = "A parameter was null: ";

    /** No-Args Constructor */
    private StringUtils() {
    }

    /**
     * Appends provided String and a trailing space to the StringBuffer.
     * <P>
     * Nullsafe - Throws an IllegalArgumentException if either the String or
     * StringBuffer objects passed as parameters is null.
     * @param aStr String to append.
     * @param aBuff StringBuffer for append.
     * @throws IllegalArgumentException If the String or StringBuffer objects
     * provided are NULL.
     */
    public static void appendWithTrailingSpace(String aStr, StringBuffer aBuff) {

        if (aStr == null) {

            LOGGER.log(Level.WARNING, NULL_PARAMETER_EX + "aStr");
            throw new IllegalArgumentException(NULL_PARAMETER_EX + "aStr");
        } else if (aBuff == null) {

            LOGGER.log(Level.WARNING, NULL_PARAMETER_EX + "aBuff");
            throw new IllegalArgumentException(NULL_PARAMETER_EX + "aBuff");
        } else {

            aBuff.append(aStr);
            aBuff.append(" ");
        }
    }

    /**
     * Null-safe implementation of StringBuffer.append.  Only performs the
     * action if the provided String and Buffer aren't NULL.  Otherwise throws
     * an IllegalArgumentException.
     * @param aStr String to append.
     * @param aBuff StringBuffer for append.
     * @throws IllegalArgumentException If the String or StringBuffer objects
     * provided are NULL.
     */
    public static void nullsafeAppend(String aStr, StringBuffer aBuff) {

        if (aStr == null) {

            LOGGER.log(Level.WARNING, NULL_PARAMETER_EX + "aStr");
            throw new IllegalArgumentException(NULL_PARAMETER_EX + "aStr");
        } else if (aBuff == null) {

            LOGGER.log(Level.WARNING, NULL_PARAMETER_EX + "aBuff");
            throw new IllegalArgumentException(NULL_PARAMETER_EX + "aBuff");
        } else {

            aBuff.append(aStr);
        }
    }

    /**
     * Null-safe appender of a String, a comma and a space to a provided
     * StringBuffer.  Only performs the action if the provided String or Buffer
     * aren't NULL.  Otherwise throws an IllegalArgumentException.
     * @param aStr String to append.
     * @param aBuff StringBuffer for append.
     * @throws IllegalArgumentException If the String or StringBuffer objects
     * provided are NULL.
     */
    public static void nullsafeAppendCommaSpace(String aStr, StringBuffer aBuff) {

        if (aStr == null) {

            LOGGER.log(Level.WARNING, NULL_PARAMETER_EX + "aStr");
            throw new IllegalArgumentException(NULL_PARAMETER_EX + "aStr");
        } else if (aBuff == null) {

            LOGGER.log(Level.WARNING, NULL_PARAMETER_EX + "aBuff");
            throw new IllegalArgumentException(NULL_PARAMETER_EX + "aBuff");
        } else {

            aBuff.append(aStr);
            aBuff.append(", ");
        }
    }

    /**
     * Null-safe appender of a String, and a comma to a provided
     * StringBuffer.  Only performs the action if the provided String is not
     * NULL.  Otherwise throws an IllegalArgumentException.
     * @param aStr String to append.
     * @param aBuff String buffer for append.
     * @throws IllegalArgumentException If the String or StringBuffer objects
     * provided are NULL.
     */
    public static void nullsafeAppendComma(String aStr, StringBuffer aBuff) {

        if (aStr == null) {

            LOGGER.log(Level.WARNING, NULL_PARAMETER_EX + "aStr");
            throw new IllegalArgumentException(NULL_PARAMETER_EX + "aStr");
        } else if (aBuff == null) {

            LOGGER.log(Level.WARNING, NULL_PARAMETER_EX + "aBuff");
            throw new IllegalArgumentException(NULL_PARAMETER_EX + "aBuff");
        } else {

            aBuff.append(aStr);
            aBuff.append(", ");
        }
    }

    /**
     * Tests to see if the provided String is NULL or of zero length.
     * @param testMe The String to test.
     * @return 'true' if the String is NULL or of zero length.
     */
    public static boolean isBlank(String testMe) {

        boolean isBlank = false;

        if (testMe == null || testMe.length() == 0) {

            isBlank = true;
        }

        return isBlank;
    }

    /**
     * Take a String which is in camel caps and return the SQL name equivalent;
     * with a '_' before each capital letter and in upper case.
     * <P>
     * E.g. thisIsAnExample becomes: THIS_IS_AN_EXAMPLE
     * <P> Nullsafe - An IllegalArgumentException is thrown if the String passed is
     * null.
     * @param aString The camel case string to SQL-ise
     * @return The SQL-ised String.
     * @throws IllegalArgumentException If the String object provided is NULL.
     */
    public static String camelCapsToSqlName(String aString) {

        // TODO: Fix the problem whereby if the string starts with a capital
        // then the SQL equivalent will statr with "_"

        StringBuffer aBuffer;

        if (aString == null) {
            LOGGER.log(Level.WARNING, NULL_PARAMETER_EX + "aString");
            throw new IllegalArgumentException(NULL_PARAMETER_EX + "aString");
        } else {
            aBuffer = new StringBuffer(aString);
        }
        
        Pattern p = Pattern.compile("[A-Z]");
        Matcher m = p.matcher(aBuffer);
        
        boolean found = m.find();
        while (found) {      
            aBuffer.replace(m.start(), m.start(), "_");
            found = m.find(m.end() + 1);
        }
        
        return aBuffer.toString().toUpperCase();
    }

    /**
     * Pad a String up to a certain size with a char on the left ('true') or
     * on the right ('false') as long as the String provided is not NULL.
     * <P>
     * Nullsafe - An IllegalArgumentException is thrown if the String passed is
     * null.
     * @param aString The String to be padded.
     * @param aLength Final intended length for the final String.
     * @param aChar The pad char.
     * @param paddingLeft 'true' - pad from left, 'false' - pad from right.
     * @return The padded String.
     * @throws IllegalArgumentException If the String object provided is NULL.
     */
    public static String paddingString(String aString, int aLength, char aChar, boolean paddingLeft) {

        StringBuffer str;

        if (aString == null) {

            LOGGER.log(Level.WARNING, NULL_PARAMETER_EX + "aString");
            throw new IllegalArgumentException(NULL_PARAMETER_EX + "aString");
        } else {

            str = new StringBuffer(aString);
        }
        int strLength = str.length();
        if (aLength > 0 && aLength > strLength) {
            for (int i = 0; i <= aLength; i++) {
                if (paddingLeft) {
                    if (i < aLength - strLength) {
                        str.insert(0, aChar);
                    }
                } else {
                    if (i > strLength) {
                        str.append(aChar);
                    }
                }
            }
        }

        return str.toString();
    }
}